<template>
  <!-- 视频播放器容器，使用相对定位以便内部元素进行绝对定位 -->
  <div class="video-player-container" ref="playerContainer">
    <!-- 视频标题栏，显示视频标题和状态指示灯 -->
    <div class="video-header">
      <!-- 使用传入的视频标题，如果没有则显示默认标题 -->
      <h3>{{ videoTitle || `视频 ${videoId}` }}</h3>
      <!-- 状态指示灯，根据当前播放状态显示不同颜色 -->
      <div class="status-indicator" :class="status"></div>
    </div>

    <!-- 视频显示区域，使用固定宽高比(16:9) -->
    <div class="video-wrapper">
      <!-- 视频元素，使用ref引用以便JavaScript操作 -->
      <video
          ref="videoElement"
          class="video-element"
          autoplay
          muted
          playsinline
      ></video>

      <!-- 加载指示器，在视频加载过程中显示 -->
      <div v-if="isLoading" class="loading-overlay">
        <div class="spinner"></div>  <!-- 加载动画 -->
        <p>{{ loadingText }}</p>      <!-- 加载状态文本 -->
      </div>

      <!-- 错误提示面板，在播放出错时显示 -->
      <div v-if="errorMessage" class="error-overlay">
        <p class="error-message">{{ errorMessage }}</p>  <!-- 错误信息 -->
        <button @click="retryPlayback" class="retry-button">重试</button>  <!-- 重试按钮 -->
      </div>

      <!-- 视频控制栏 -->
      <div v-if="showControls" class="video-controls">
        <button @click="togglePlay" class="control-button">
          {{ isPlaying ? '暂停' : '播放' }}
        </button>
        <button @click="toggleFullscreen" class="control-button">
          {{ isFullscreen ? '退出全屏' : '全屏' }}
        </button>
      </div>
    </div>

    <!-- 播放统计信息面板，可通过props控制是否显示 -->
    <div v-if="showStats" class="stats-panel">
      <p>缓冲: {{ bufferLength.toFixed(1) }}s</p>       <!-- 缓冲区长度 -->
      <p>延迟: {{ latency.toFixed(1) }}s</p>           <!-- 加载延迟 -->
      <p>带宽: {{ bandwidthMbps.toFixed(2) }} Mbps</p> <!-- 网络带宽 -->
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted, onUnmounted, watch, computed, nextTick } from 'vue';
import flvjs from 'flv.js';
import { getVideoStreamUrl, stopVideoTranscode } from '@/api/VideoPlayer.js';

// 组件props定义
const props = defineProps({
  videoId: {
    type: Number,
    required: true  // 必需的视频ID参数
  },
  videoTitle: {
    type: String,
    default: ''    // 视频标题，默认为空
  },
  autoPlay: {
    type: Boolean,
    default: true  // 是否自动播放
  },
  showStats: {
    type: Boolean,
    default: false // 是否显示播放统计信息
  }
});

// 组件状态管理
const videoElement = ref(null);       // 视频DOM元素引用
const playerContainer = ref(null);    // 播放器容器引用
const flvPlayer = ref(null);          // FLV播放器实例
const status = ref('offline');        // 播放状态：offline, connecting, online, error
const isLoading = ref(true);          // 是否正在加载
const loadingText = ref('正在连接...'); // 加载状态文本
const errorMessage = ref('');         // 错误信息
const bufferLength = ref(0);          // 缓冲区长度(秒)
const latency = ref(0);               // 加载延迟(秒)
const bandwidthMbps = ref(0);         // 网络带宽(Mbps)
const reconnectAttempts = ref(0);     // 重连尝试次数
const maxReconnectAttempts = ref(5);  // 最大重连尝试次数
const reconnectTimer = ref(null);     // 重连计时器
const isPlaying = ref(true);         // 是否正在播放
const isFullscreen = ref(false);      // 是否全屏状态

// 计算属性：是否显示控制栏
const showControls = computed(() => status.value === 'online');

/**
 * 切换播放/暂停状态
 */
const togglePlay = async () => {
  if (!videoElement.value) return;

  if (isPlaying.value) {
    videoElement.value.pause();
  } else {
    try {
      await videoElement.value.play();
    } catch (err) {
      console.error('播放失败:', err);
      errorMessage.value = `播放失败: ${err.message}`;
    }
  }
  isPlaying.value = !isPlaying.value;
};

/**
 * 切换全屏状态
 */
const toggleFullscreen = () => {
  if (!playerContainer.value) return;

  if (!isFullscreen.value) {
    enterFullscreen();
  } else {
    exitFullscreen();
  }
};

/**
 * 进入全屏模式
 */
const enterFullscreen = () => {
  const element = playerContainer.value;

  if (element.requestFullscreen) {
    element.requestFullscreen();
  } else if (element.webkitRequestFullscreen) { /* Safari */
    element.webkitRequestFullscreen();
  } else if (element.msRequestFullscreen) { /* IE11 */
    element.msRequestFullscreen();
  }
};

/**
 * 退出全屏模式
 */
const exitFullscreen = () => {
  if (document.exitFullscreen) {
    document.exitFullscreen();
  } else if (document.webkitExitFullscreen) { /* Safari */
    document.webkitExitFullscreen();
  } else if (document.msExitFullscreen) { /* IE11 */
    document.msExitFullscreen();
  }
};

/**
 * 监听全屏变化事件
 */
const handleFullscreenChange = () => {
  isFullscreen.value = !!document.fullscreenElement;
};


/**
 * 初始化FLV播放器
 * @param {string} streamUrl - FLV视频流地址
 */
const initFlvPlayer = async (streamUrl) => {
  try {
    // 检查视频元素是否存在
    if (!videoElement.value) return;

    // 检查浏览器是否支持FLV播放
    if (!flvjs.isSupported()) {
      throw new Error('当前浏览器不支持FLV播放');
    }

    // 如果已有播放器实例，先销毁
    if (flvPlayer.value) {
      destroyPlayer();
    }

    // 更新状态为连接中
    status.value = 'connecting';
    isLoading.value = true;
    loadingText.value = '正在连接视频流...';
    errorMessage.value = '';

    // 创建FLV播放器实例
    flvPlayer.value = flvjs.createPlayer(
        {
          type: 'flv',                  // 流类型为FLV
          url: streamUrl,               // 视频流地址
          isLive: true,                 // 直播模式
          hasAudio: false,              // 禁用音频
          hasVideo: true,               // 启用视频
          enableWorker: true,           // 启用WebWorker进行解析，提高性能
          enableStashBuffer: false,     // 禁用累积缓冲，减少延迟
          stashInitialSize: 128,        // 初始缓冲大小(KB)
          lazyLoadMaxDuration: 3 * 60,  // 延迟加载最大时长(秒)
          networkIdleTimeout: 15.0,     // 网络空闲超时时间(秒)
          autoCleanupSourceBuffer: true, // 自动清理旧的视频片段，节省内存
          seekType: 'range'            // 使用range请求
        },
        {
          enableStatistics: true // 启用播放统计信息
        }
    );

    // 将播放器附加到视频元素
    flvPlayer.value.attachMediaElement(videoElement.value);

    // 监听播放器事件：加载完成
    flvPlayer.value.on(flvjs.Events.LOADING_COMPLETED, () => {
      console.log('视频流加载完成');
    });

    // 监听播放器事件：元数据到达
    flvPlayer.value.on(flvjs.Events.METADATA_ARRIVED, () => {
      console.log('视频元数据已加载');
      status.value = 'online';       // 更新状态为在线
      isLoading.value = false;       // 加载完成
      reconnectAttempts.value = 0;   // 重置重连次数
    });

    // 监听播放器事件：统计信息更新
    flvPlayer.value.on(flvjs.Events.STATISTICS_INFO, (stats) => {
      // 更新播放统计信息
      bufferLength.value = stats.bufferLength;       // 缓冲区长度
      latency.value = stats.loadingTime;             // 加载延迟
      bandwidthMbps.value = stats.bandwidth / 1000 / 1000; // 转换带宽单位为Mbps
    });

    // 错误处理
    flvPlayer.value.on(flvjs.Events.ERROR, (errorType, errorDetail, errorInfo) => {
      console.error('FLV播放错误:', errorType, errorDetail, errorInfo);

      // 根据错误类型设置不同的错误信息
      if (errorType === flvjs.ErrorTypes.NETWORK_ERROR) {
        errorMessage.value = `网络错误: ${errorDetail}`;
      } else if (errorType === flvjs.ErrorTypes.MEDIA_ERROR) {
        errorMessage.value = `媒体错误: ${errorDetail}`;
      } else {
        errorMessage.value = `未知错误: ${errorDetail}`;
      }

      status.value = 'error';      // 更新状态为错误
      isLoading.value = false;     // 加载完成

      // 如果未达到最大重连次数，则安排重连
      if (reconnectAttempts.value < maxReconnectAttempts.value) {
        scheduleReconnect();
      }
    });

    // 加载并播放视频
    flvPlayer.value.load();

    // 如果启用自动播放，则开始播放
    if (props.autoPlay) {
      await videoElement.value.play();
    }
  } catch (error) {
    console.error('初始化播放器失败:', error);
    errorMessage.value = `初始化播放器失败: ${error.message}`;
    status.value = 'error';
    isLoading.value = false;

    // 如果未达到最大重连次数，则安排重连
    if (reconnectAttempts.value < maxReconnectAttempts.value) {
      scheduleReconnect();
    }
  }
};

/**
 * 从后端获取视频流地址
 */
const fetchPlayUrl = async () => {
  try {
    status.value = 'connecting';  // 更新状态为连接中
    isLoading.value = true;       // 显示加载状态
    // 更新加载文本，显示当前重试次数
    loadingText.value = `正在获取视频地址 (${reconnectAttempts.value + 1}/${maxReconnectAttempts.value})...`;

    // 调用后端API获取视频流地址
    const response = await getVideoStreamUrl(1);

    // 检查响应是否有效
    if (!response || !response.url) {
      throw new Error('获取视频URL失败');
    }

    console.log('获取视频URL成功:', response.url);
    await initFlvPlayer(response.url);  // 初始化播放器
  } catch (error) {
    console.error('获取视频地址错误:', error);
    errorMessage.value = `获取视频地址失败: ${error.message}`;
    status.value = 'error';
    isLoading.value = false;

    // 如果未达到最大重连次数，则安排重连
    if (reconnectAttempts.value < maxReconnectAttempts.value) {
      scheduleReconnect();
    }
  }
};

/**
 * 安排自动重连
 */
const scheduleReconnect = () => {
  // 清除已有的重连计时器
  if (reconnectTimer.value) {
    clearTimeout(reconnectTimer.value);
  }

  // 增加重连尝试次数
  reconnectAttempts.value += 1;

  // 计算重连延迟时间，使用退避策略（最多5秒）
  const delay = Math.min(5, reconnectAttempts.value) * 1000;

  // 更新加载文本，显示重连倒计时
  loadingText.value = `连接失败，${delay / 1000}秒后重试 (${reconnectAttempts.value}/${maxReconnectAttempts.value})...`;
  isLoading.value = true;

  // 设置定时器，延迟后尝试重连
  reconnectTimer.value = setTimeout(() => {
    fetchPlayUrl();
  }, delay);
};

/**
 * 手动重试播放
 */
const retryPlayback = () => {
  // 清除已有的重连计时器
  if (reconnectTimer.value) {
    clearTimeout(reconnectTimer.value);
  }

  // 重置重连次数
  reconnectAttempts.value = 0;

  // 重新获取视频地址
  fetchPlayUrl();
};

/**
 * 销毁播放器实例
 */
const destroyPlayer = () => {
  if (flvPlayer.value) {
    // 卸载资源，分离媒体元素，销毁播放器
    flvPlayer.value.unload();
    flvPlayer.value.detachMediaElement();
    flvPlayer.value.destroy();
    flvPlayer.value = null;
  }

  // 清除重连计时器
  if (reconnectTimer.value) {
    clearTimeout(reconnectTimer.value);
    reconnectTimer.value = null;
  }
};

   
  

// 组件挂载时执行初始化
onMounted(() => {
  fetchPlayUrl();  // 获取视频地址并初始化播放器

  // 添加全屏变化事件监听
  document.addEventListener('fullscreenchange', handleFullscreenChange);
  document.addEventListener('webkitfullscreenchange', handleFullscreenChange);
  document.addEventListener('msfullscreenchange', handleFullscreenChange);
});

// 组件卸载时执行清理工作
onUnmounted(() => {
  destroyPlayer();  // 销毁播放器实例

  // 移除全屏事件监听
  document.removeEventListener('fullscreenchange', handleFullscreenChange);
  document.removeEventListener('webkitfullscreenchange', handleFullscreenChange);
  document.removeEventListener('msfullscreenchange', handleFullscreenChange);

  // 通知后端停止视频转码，节省服务器资源
  if (props.videoId) {
    stopVideoTranscode(1).catch(err => {
      
      console.warn('停止转码失败:', err);
    });
  }
});

// 监听videoId变化（保持原有代码不变）
// ...
</script>

<style scoped>
/* 原有样式保持不变... */
/* 视频播放器容器样式 */
.video-player-container {
  position: relative;           /* 相对定位，作为内部绝对定位元素的参考 */
  width: 100%;                  /* 宽度占满父容器 */
  max-width: 800px;             /* 最大宽度限制 */
  margin: 0 auto;               /* 水平居中 */
  background-color: #000;       /* 背景颜色为黑色 */
  border-radius: 8px;           /* 圆角 */
  overflow: hidden;             /* 超出部分隐藏 */
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); /* 阴影效果 */
}

/* 视频标题栏样式 */
.video-header {
  position: relative;           /* 相对定位 */
  display: flex;                /* 使用flex布局 */
  align-items: center;          /* 垂直居中对齐 */
  padding: 12px 16px;           /* 内边距 */
  background-color: #1a1a1a;    /* 深灰色背景 */
  color: white;                 /* 白色文字 */
}

.video-header h3 {
  margin: 0;                    /* 移除默认边距 */
  font-size: 1rem;              /* 字体大小 */
  font-weight: 500;             /* 字体粗细 */
  flex: 1;                      /* 占据剩余空间 */
}

/* 状态指示灯样式 */
.status-indicator {
  width: 12px;                  /* 宽度 */
  height: 12px;                 /* 高度 */
  border-radius: 50%;           /* 圆形 */
  margin-left: 8px;             /* 左边距 */
  animation: pulse 2s infinite; /* 呼吸动画 */
}

/* 不同状态下的指示灯颜色 */
.status-indicator.online {
  background-color: #2ecc71;    /* 绿色：在线 */
  animation: none;              /* 取消动画 */
}

.status-indicator.offline {
  background-color: #e74c3c;    /* 红色：离线 */
}

.status-indicator.connecting {
  background-color: #f39c12;    /* 黄色：连接中 */
}

.status-indicator.error {
  background-color: #e74c3c;    /* 红色：错误 */
}

/* 视频包装器样式，使用padding-bottom实现固定宽高比(16:9) */
.video-wrapper {
  position: relative;           /* 相对定位 */
  width: 100%;                  /* 宽度占满父容器 */
  padding-bottom: 56.25%;       /* 16:9的宽高比 */
}

/* 视频元素样式 */
.video-element {
  position: absolute;           /* 绝对定位 */
  top: 0;                       /* 顶部对齐 */
  left: 0;                      /* 左侧对齐 */
  width: 100%;                  /* 宽度占满父容器 */
  height: 100%;                 /* 高度占满父容器 */
  object-fit: cover;            /* 保持视频比例，覆盖容器 */
}

/* 加载覆盖层样式 */
.loading-overlay {
  position: absolute;           /* 绝对定位 */
  top: 0;                       /* 顶部对齐 */
  left: 0;                      /* 左侧对齐 */
  width: 100%;                  /* 宽度占满父容器 */
  height: 100%;                 /* 高度占满父容器 */
  display: flex;                /* 使用flex布局 */
  flex-direction: column;       /* 垂直排列 */
  align-items: center;          /* 水平居中对齐 */
  justify-content: center;      /* 垂直居中对齐 */
  background-color: rgba(0, 0, 0, 0.7); /* 半透明黑色背景 */
  color: white;                 /* 白色文字 */
  z-index: 10;                  /* 层级较高 */
}

/* 加载旋转动画 */
.spinner {
  width: 40px;                  /* 宽度 */
  height: 40px;                 /* 高度 */
  border: 3px solid rgba(255, 255, 255, 0.3); /* 浅灰色边框 */
  border-radius: 50%;           /* 圆形 */
  border-top-color: #409eff;    /* 蓝色顶部边框 */
  animation: spin 1s linear infinite; /* 旋转动画 */
  margin-bottom: 16px;          /* 底部边距 */
}

/* 错误覆盖层样式 */
.error-overlay {
  position: absolute;           /* 绝对定位 */
  top: 0;                       /* 顶部对齐 */
  left: 0;                      /* 左侧对齐 */
  width: 100%;                  /* 宽度占满父容器 */
  height: 100%;                 /* 高度占满父容器 */
  display: flex;                /* 使用flex布局 */
  flex-direction: column;       /* 垂直排列 */
  align-items: center;          /* 水平居中对齐 */
  justify-content: center;      /* 垂直居中对齐 */
  background-color: rgba(0, 0, 0, 0.7); /* 半透明黑色背景 */
  color: white;                 /* 白色文字 */
  z-index: 10;                  /* 层级较高 */
}

.error-message {
  margin-bottom: 16px;          /* 底部边距 */
  color: #f56c6c;               /* 红色错误信息 */
  text-align: center;           /* 文字居中 */
}

.retry-button {
  background-color: #409eff;    /* 蓝色背景 */
  color: white;                 /* 白色文字 */
  border: none;                 /* 无边框 */
  border-radius: 4px;           /* 圆角 */
  padding: 8px 16px;            /* 内边距 */
  cursor: pointer;              /* 光标样式 */
  transition: background-color 0.2s; /* 背景色过渡动画 */
}

.retry-button:hover {
  background-color: #3a8ee6;    /* 悬停时颜色变深 */
}

/* 统计信息面板样式 */
.stats-panel {
  position: absolute;           /* 绝对定位 */
  bottom: 0;                    /* 底部对齐 */
  left: 0;                      /* 左侧对齐 */
  right: 0;                     /* 右侧对齐 */
  padding: 8px 16px;            /* 内边距 */
  background-color: rgba(0, 0, 0, 0.7); /* 半透明黑色背景 */
  color: white;                 /* 白色文字 */
  font-size: 0.8rem;            /* 字体大小 */
  display: flex;                /* 使用flex布局 */
  justify-content: space-around; /* 均匀分布内容 */
  z-index: 5;                   /* 层级适中 */
}

/* 动画定义 */
@keyframes spin {
  to {
    transform: rotate(360deg);  /* 旋转360度 */
  }
}

@keyframes pulse {
  0% {
    opacity: 0.5;               /* 透明度0.5 */
  }
  50% {
    opacity: 1;                 /* 透明度1 */
  }
  100% {
    opacity: 0.5;               /* 透明度0.5 */
  }
}
/* 视频控制栏样式 */
.video-controls {
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  padding: 10px;
  background: linear-gradient(to top, rgba(0,0,0,0.7), transparent);
  display: flex;
  justify-content: flex-end;
  gap: 10px;
  opacity: 0;
  transition: opacity 0.3s ease;
}

.video-wrapper:hover .video-controls {
  opacity: 1;
}

.control-button {
  background-color: rgba(0, 0, 0, 0.5);
  color: white;
  border: 1px solid rgba(255, 255, 255, 0.2);
  border-radius: 4px;
  padding: 5px 10px;
  cursor: pointer;
  font-size: 0.9rem;
  transition: all 0.2s ease;
}

.control-button:hover {
  background-color: rgba(0, 0, 0, 0.7);
  border-color: rgba(255, 255, 255, 0.4);
}

/* 全屏模式下的样式调整 */
:fullscreen .video-player-container {
  width: 100%;
  height: 100%;
  max-width: none;
  display: flex;
  flex-direction: column;
}

:fullscreen .video-wrapper {
  flex: 1;
  padding-bottom: 0;
}

/* 浏览器前缀兼容 */
:-webkit-full-screen .video-player-container {
  width: 100%;
  height: 100%;
  max-width: none;
  display: flex;
  flex-direction: column;
}

:-webkit-full-screen .video-wrapper {
  flex: 1;
  padding-bottom: 0;
}

:-ms-fullscreen .video-player-container {
  width: 100%;
  height: 100%;
  max-width: none;
  display: flex;
  flex-direction: column;
}

:-ms-fullscreen .video-wrapper {
  flex: 1;
  padding-bottom: 0;
}
</style>
